package com.atguigu.spzx.product.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.model.entity.product.Category;
import com.atguigu.spzx.product.mapper.CategoryMapper;
import com.atguigu.spzx.product.service.CategoryService;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * ClassName: CategoryServiceImpl
 * Package: com.atguigu.spzx.product.service.impl
 * Description:
 *
 * @Author 刘强
 * @Create 2024/7/14 12:48
 * @Version 1.0
 */
@Service
public class CategoryServiceImpl implements CategoryService {
    @Resource
    private CategoryMapper categoryMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 查询一级分类
     * 通过redis做缓存
     * 先从redis中查询数据，如果查询到，则直接返回。如果查询不到，则从数据库中查询数据，然后缓存到redis中，然后再返回。
     *
     * @return
     */
    @Override
    public List<Category> findOneCategory() {
        // 1. 从redis中查询数据
        String categoryOneListJson = stringRedisTemplate.opsForValue().get("category:one");
        // 2. 判断是否为空，如果不为空，则直接返回；如果为空则从mysql中查询数据，然后缓存到redis中，再返回
        if (!StrUtil.isEmpty(categoryOneListJson)) {
            List<Category> categoryList = JSON.parseArray(categoryOneListJson, Category.class);
            return categoryList;
        }
        List<Category> categoryOneList = categoryMapper.findOneCategory();
        stringRedisTemplate.opsForValue().set("category:one", JSON.toJSONString(categoryOneList), 7, TimeUnit.DAYS);

        return categoryOneList;
    }

    /**
     * 查询所有分类 -> 树形结构
     *
     * @return
     */
    @Override
    @Cacheable(value = "category" ,key = "'all'")
    public List<Category> findCategoryTree() {
        // 1. 查询所有分类
        List<Category> categoryList = categoryMapper.findAll();
        // 2. 构建树形结构
        //    2.1 获取一级分类
        if (CollectionUtils.isEmpty(categoryList)) {
            return null;
        }

        List<Category> categoryOneListTree = buildTree(categoryList, 0);
        return categoryOneListTree;
    }


    private List<Category> buildTree(List<Category> categoryList, int parentId) {
        if (CollectionUtils.isEmpty(categoryList)) {
            return null;
        }
        List<Category> categoryOneList = categoryList.stream()
                .filter(category -> category.getParentId().intValue() == 0).collect(Collectors.toList());
        setChildren(categoryOneList, categoryList);
        return categoryOneList;
    }

    public void setChildren(List<Category> categoryNList, List<Category> categorieList) {
        // 递归结束条件
        if (CollectionUtils.isEmpty(categoryNList)) {
            return;
        }
        for (Category categoryN : categoryNList) {
            ArrayList<Category> children = new ArrayList<>();
            for (Category category : categorieList) {
                if (categoryN.getId().intValue() == category.getParentId().intValue()) {
                    children.add(category);
                }
            }
            categoryN.setChildren(children);
            if (CollectionUtils.isEmpty(children)) {
                categoryN.setHasChildren(false);
                continue;
            }
            setChildren(children, categorieList);
        }
    }


}
